package org.bookie.web.pages.admin;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.apache.tapestry.annotations.InjectObject;
import org.apache.tapestry.event.PageBeginRenderListener;
import org.apache.tapestry.event.PageEvent;
import org.bookie.framework.CommonBasePage;
import org.bookie.model.Bet;
import org.bookie.model.Outcome;
import org.bookie.model.Role;
import org.bookie.model.security.Access;
import org.bookie.model.services.BetDAO;
import org.bookie.model.services.OutcomeDAO;

@Access(role=Role.ADMIN)
public abstract class AddResult extends CommonBasePage implements PageBeginRenderListener{
	public static final String CONTENT = "eventTable";
	public static final String RESULT_LIST = "resultList";
	
	public void pageBeginRender(PageEvent event) {
		if(null==getBets()){
			setBets(getBetDAO().findExpired());
		}
		if(null==getResults()){
			setResults(new ArrayList<Outcome>());
		}
	}

	public void addResult(Long id) {
		Outcome outcome = getOutcomeDAO().findById(id);
		if(null!=outcome){
			if(validate(outcome)){
				getResults().add(outcome);
			}
			updateComponents();
		}

	}
	
	public void storeResults(){
		Iterator iter = getResults().iterator();
		while(iter.hasNext()){
			Outcome outcome = (Outcome)iter.next();
			getBetDAO().finalise(outcome);
			setResults(null);
		}
		setMessage(getMessages().getMessage("admin.addresult.success.message"));
		updateComponents();
	}
	
	public void deleteResult(Long id){
		Outcome outcome = findBet(id);
		if(outcome!=null){
			getResults().remove(outcome);
		}
		updateComponents();
	}
	
	private void updateComponents(){
		updateComponents(RESULT_LIST, CONTENT);
	}
	
	private boolean validate(Outcome outcome){
		if(null!=findBet(outcome.getId())){
			formatError("admin.addresult.error.bet.duplicate", outcome.getLabel());
			return false;
		}
		if(isResultSelected(outcome)){
			Bet bet = outcome.getBet();
			formatError("admin.addresult.error.event.duplicate",
					bet.getEvent().getLabel()+": "+bet.getLabel());
			return false;
		}
		return true;
	}

	public boolean isResultSelected(Outcome outcome){
		Iterator<Outcome> iter = getResults().iterator();
		while(iter.hasNext()){
			Outcome next = iter.next();
			if(next.getBet().getId().equals(outcome.getBet().getId())){
				return true;
			}
		}
		return false;
	}
	
	private Outcome findBet(Long id){
		Iterator<Outcome> iter = getResults().iterator();
		while(iter.hasNext()){
			Outcome next = iter.next();
			if(next.getId().equals(id)){
				return next;
			}
		}
		return null; 
	}
	
	/**
	 * Injected service
	 */
	@InjectObject("service:bookie.model.BetDAO")
	public abstract BetDAO getBetDAO();
	/**
	 * Injected service
	 * @return
	 */
	@InjectObject("service:bookie.model.OutcomeDAO")
	public abstract OutcomeDAO getOutcomeDAO();
	
	public abstract Collection<Bet> getBets();
	public abstract void setBets(Collection<Bet> bets);
	
	public abstract Collection<Outcome> getResults();
	public abstract void setResults(Collection<Outcome> results);

}
